package com.wangwenjun.concurrency.chapter14.reentrantreadwritelock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReentrantReadWriteLockDemo {


    public static void main(String[] args) {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        ReadThread rt1 = new ReadThread("rt1", lock);
        ReadThread rt2 = new ReadThread("rt2", lock);
        WriteThread wt1 = new WriteThread("wt1", lock);
        rt1.start();
        rt2.start();
        wt1.start();
    }



}

class ReadThread extends Thread{

    private ReentrantReadWriteLock lock;

    public ReadThread(String name, ReentrantReadWriteLock lock){
        super(name);
        this.lock = lock;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" try get lock");
        lock.readLock().lock();
        try{
            System.out.println(Thread.currentThread().getName()+" get lock successfully");
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            lock.readLock().unlock();
            System.out.println(Thread.currentThread().getName()+" release lock successfully");
        }
    }

}


class WriteThread extends Thread{

    private ReentrantReadWriteLock lock;

    public WriteThread(String name, ReentrantReadWriteLock lock){
        super(name);
        this.lock = lock;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" try get lock");
        lock.writeLock().lock();
        try{
            System.out.println(Thread.currentThread().getName()+" get lock successfully");
        } finally {
            lock.writeLock().unlock();
            System.out.println(Thread.currentThread().getName()+" release lock successfully");
        }
    }

}
